package context.environ;

import math.vec2i;
import org.lwjgl.LWJGLException;

public class Mouse
{
    
    private static Mouse singleton = new Mouse();
    
    public static Mouse get()
    {
        return Mouse.singleton;
    }
    
    private Mouse()
    {
    }
    
    
    private static final int NUM_BUTTONS = 3;
    
    public static final int CLICK_L = 0;
    public static final int CLICK_R = 1;
    public static final int CLICK_MID = 2;
    
    
    public int mDeltaWheel;
    
    public vec2i mScreenPos;
    
    public vec2i mDeltaPos;
    
    public double mSensitivity;
    
    private boolean[] mStateCur;
    private boolean[] mStatePrev;
    
    private boolean mIsGrabbed;
    
    
    public void onStart()
    {
        this.mStateCur = new boolean[Mouse.NUM_BUTTONS];
        this.mStatePrev = new boolean[Mouse.NUM_BUTTONS];
        
        this.mScreenPos = new vec2i();
        this.mDeltaPos = new vec2i();
        
        this.mIsGrabbed = true;
        
        this.mSensitivity = 0.01;
        
        this.initMouse();
    }
    
    public void setGrabbed(boolean aMouseGrabbed)
    {
        this.mIsGrabbed = aMouseGrabbed;
        org.lwjgl.input.Mouse.setGrabbed(this.mIsGrabbed);
    }
    
    public void onTick()
    {
        this.mScreenPos.x = org.lwjgl.input.Mouse.getX();
        this.mScreenPos.y = org.lwjgl.input.Mouse.getY();
        
        this.mDeltaPos.x = org.lwjgl.input.Mouse.getDX();
        this.mDeltaPos.y = org.lwjgl.input.Mouse.getDY();
        
        this.mDeltaWheel = org.lwjgl.input.Mouse.getDWheel();
        
        for (int i = 0; i < Mouse.NUM_BUTTONS; i++)
        {
            boolean isDown = org.lwjgl.input.Mouse.isButtonDown(i);
            this.mStatePrev[i] = this.mStateCur[i];
            this.mStateCur[i] = isDown;
        }
    }
    
    public void onEnd()
    {
        org.lwjgl.input.Mouse.destroy();
        this.mScreenPos = null;
        this.mDeltaPos = null;
        this.mStateCur = null;
        this.mStatePrev = null;
    }
    
    
    public boolean isDown(final int aButton)
    {
        boolean isDown = this.mStateCur[aButton];
        return isDown;
    }
    
    public boolean isPressed(final int aButton)
    {
        boolean pressed = (this.mStateCur[aButton] && !this.mStatePrev[aButton]);
        return pressed;
    }
    
    public boolean isReleased(final int aButton)
    {
        boolean released = (!this.mStateCur[aButton] && this.mStatePrev[aButton]);
        return released;
    }
    
    
    private void initMouse()
    {
        try
        {
            org.lwjgl.input.Mouse.create();
            org.lwjgl.input.Mouse.setGrabbed(this.mIsGrabbed);
        }
        catch (LWJGLException e)
        {
            System.err.println(e);
            System.exit(1);
        }
    }
    
}
